package com.ft.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ft.dao.AnswerDao;
import com.ft.dao.FistcommentDao;
import com.ft.dao.PostDao;
import com.ft.domain.Post;
import com.ft.service.IPostService;
import com.ft.utils.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: ft
 * @Date: 2023/01/11/17:06
 * @Description:
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostDao, Post> implements IPostService {
    @Autowired
    private PostDao postDao;
    @Autowired
    private FistcommentDao fistcommentDao;
    @Autowired
    private AnswerDao answerDao;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 增加帖子
     */
    @Override
    public int addPost(Post post) throws IllegalAccessException {
        int i = postDao.addPost(post);
        if(i == 1){
            //1.将帖子id存入缓存
            String id = String.valueOf (post.getId ());
            redisTemplate.opsForZSet().add("postId",id,0);
            //将帖子信息存入缓存
            String postKey1 = "post:"+post.getId ();
            Map<String, Object> stringObjectMap = ObjectUtils.objectToMap (post);
            redisTemplate.opsForHash ().putAll (postKey1, stringObjectMap);
            //同步帖子创建时间
            redisTemplate.opsForHash().delete(postKey1,"createTime");
            String time = postDao.getcreateTime(post.getId ());
            redisTemplate.opsForHash().put(postKey1,"createTime",time);
            //检查是数据否添加成功
            Long  hashOrderSize = redisTemplate.opsForHash().size (postKey1);
            while (true){
                //结束条件,验证每个字段是否都添加上了
                if(hashOrderSize == Post.total){
                    break;
                }
                if(hashOrderSize != Post.total){
                    //移除key
                    redisTemplate.delete (postKey1);
                    //重新添加
                    Map<String, Object> stringObjectMap1 = ObjectUtils.objectToMap (post);
                    Set mapkey1 = stringObjectMap1.keySet ();
                    for(Object key : mapkey1){
                        redisTemplate.opsForHash().put(postKey1,key,stringObjectMap.get (key));
                    }
                }
            }
            return i;
        }else {
            return i;
        }
    }

    /**
     * 获取帖子信息
     * page 分页页数
     * @return
     */
    @Override
    public List getPostList(int type,int page) {
        //同类型的集合数据
        List resulttype = new ArrayList ();
        //返回的数据
        List result = new ArrayList ();
        //获取所有订单数据
        Set lostarticleId = redisTemplate.opsForZSet ().reverseRangeByScore("postId", 0, 99);
        //遍历set获取同类型的数据
        for(Object le : lostarticleId){
            Map entries = redisTemplate.opsForHash ().entries ("post:" + le);
            int T = (int) entries.get ("type");
            if(T == type + 1){
                //对id进行处理
                Object id = entries.get ("id");
                entries.put ("id",""+id);
                resulttype.add (entries);
            }
        }
        //如果数据小于5的情况
        if(resulttype.size() < 5){
            for(int i = 0;i < resulttype.size(); i++){
                //将map转成对象
                result.add (JSONObject.parseObject(JSONObject.toJSONString(resulttype.get(i)), Post.class));
            }
            return result;
        }else {
            //每次返回5个数据，total：获取数据结束的位置
            int total = 0;
            //每次获取数据循环开始的位置
            int num = page * 5;
            if(page == 0){
                total = 5;
            }else {
                total = (page+1) * 5;
            }
            for (;num < total & num < resulttype.size(); num++){
                Post post = JSONObject.parseObject (JSONObject.toJSONString (resulttype.get (num)), Post.class);
                result.add (post);
            }
            return result;
        }
    }

    /**
     * 更新点赞功能
     * @param praise
     * @param number 点赞数
     * @param id 点赞帖子id
     * @return
     */
    @Override
    public int addPraiseAndNumber(String praise, int number,Long id) {
        int i = postDao.addAndUpdatePraiseAndNumber (praise, number,id);
        if(i == 1){
            //修改redis中对应字段
            redisTemplate.opsForHash().put("post:"+id,"praiseUseridlist",praise);
            redisTemplate.opsForHash().put("post:"+id,"praisenum",number);
            return 1;
        }
        return 0;
    }

    /**
     * 搜索内容
     * @param content 搜索的内容
     * @param type 搜索的类型
     * @return
     */
    @Override
    public List search(String content,int type,int page) {
        //返回结果集合
        List result = new ArrayList ();
        //获取订单数据
        Set postId = redisTemplate.opsForZSet ().reverseRangeByScore("postId", 0, 99);
        //遍历集合取出数据
        for(Object key : postId){
            Map entries = redisTemplate.opsForHash ().entries ("post:" + key);
            String ct = (String) entries.get ("content");
            Integer type1 = (Integer) entries.get ("type");
            if(type1 == type+1 & ct.contains (content) ){
                //对id进行处理
                Object id = entries.get ("id");
                entries.put ("id",""+id);
                result.add(entries);
            }
        }
        //数据小于50的情况
        if(result.size() < 50){
            return result;
        }else {
            List ids = new ArrayList();
            //每次返回5个数据，total：获取数据结束的位置
            int total = 0;
            //每次获取数据循环开始的位置
            int num = page * 50;
            if(page == 0){
                total = 50;
            }else {
                total = (page+1) * 50;
            }
            for(;num < total & num < result.size (); num++){
                ids.add (result.get(num));
            }
            return ids;
        }
    }
    @Override
    public String getPostcommentNum(Long id) {
        String praiseUseridlist = (String) redisTemplate.opsForHash ().get ("post:" + id, "praiseUseridlist");
        return praiseUseridlist;
    }
    //删除帖子
    @Override
    public int deletePost(Long id){
        //删除评论，回复的标记大于零就是删除了
        //1.获取帖子的所有评论id集合
        String commentidList = postDao.getCommentidList (id);
        String[] idList = new String[0];
        //有评论的情况
        if(commentidList != null & commentidList.length () >0){
            idList = commentidList.split (",");
            //获取每个评论的回复,并删除
            for(int i = 0; i < idList.length; i++){
                String answerIdlist = fistcommentDao.getAnswerIdlist (Long.valueOf (idList[i]));
                if(answerIdlist != null & answerIdlist.length () > 0){
                    String[] answerSting = answerIdlist.split(",");
                    //删除redis中的回复hash
                    for(int j = 0; j < answerSting.length; j++){
                        redisTemplate.delete ("answer:"+ answerSting[j]);
                        //删除回复zet中对应id
                        redisTemplate.boundZSetOps("answerId").remove(""+answerSting[j]);
                    }
                    int i1 = answerDao.deleteAnswerArray (answerSting);
                }
                //删除redis中评论数据
                redisTemplate.delete ("fistcomment:"+ idList[i]);
                //删除回复zet中对应id
                redisTemplate.boundZSetOps("fistcommentId").remove(""+idList[i]);
            }
            //删除redis中帖子数据
            redisTemplate.delete ("post:"+ id);
            //删除回复zet中对应id
            redisTemplate.boundZSetOps("postId").remove(""+id);
            int i = fistcommentDao.deletefistcommentArray (idList);
            int j = postDao.deletePost (id);
            if(i > 0 && j == 1){
                return 1;
            }
            return 0;
        }
        int j = postDao.deletePost (id);
        if( j == 1){
            //删除redis中帖子数据
            redisTemplate.delete ("post:"+ id);
            //删除回复zet中对应id
            redisTemplate.boundZSetOps("postId").remove(""+id);
            return 1;
        }
        return 0;
    }
}
